home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / archiver / unix / zip19p1.zoo / zip.c < prev    next >
C/C++ Source or Header  |  1992-08-20  |  33KB  |  1,089 lines

  1. /*
  2.  
  3.  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  4.  Kai Uwe Rommel and Igor Mandrichenko.
  5.  Permission is granted to any individual or institution to use, copy, or
  6.  redistribute this software so long as all of the original files are included
  7.  unmodified, that it is not sold for profit, and that this copyright notice
  8.  is retained.
  9.  
  10. */
  11.  
  12. /*
  13.  *  zip.c by Mark Adler.
  14.  */
  15.  
  16. #include "revision.h"
  17. #include "zip.h"
  18. #ifdef VMS
  19. #  include "VMSmunch.h"
  20. #  define echon() echo(1)
  21. #endif
  22. #include <signal.h>
  23.  
  24. #ifdef MACOS
  25. #  include <console.h>
  26. #endif
  27.  
  28. #define PWLEN 80        /* Input buffer size for reading encryption key */
  29. #define MAXCOM 256      /* Maximum one-line comment size */
  30.  
  31.  
  32. /* Local option flags */
  33. #define DELETE  0
  34. #define ADD     1
  35. #define UPDATE  2
  36. #define FRESHEN 3
  37. local int action = ADD; /* one of ADD, UPDATE, FRESHEN, or DELETE */
  38. local int comadd = 0;   /* 1=add comments for new files */
  39. local int zipedit = 0;  /* 1=edit zip comment and all file comments */
  40. local int dispose = 0;  /* 1=remove files after put in zip file */
  41. local int latest = 0;   /* 1=set zip file time to time of latest file */
  42. local ulg before = 0;   /* 0=ignore, else exclude files before this time */
  43.  
  44.  
  45. /* Temporary zip file name and file pointer */
  46. local char *tempzip;
  47. local FILE *tempzf;
  48.  
  49.  
  50. /* Local functions */
  51. #ifdef PROTO
  52.    local void freeup(void);
  53.    local void leave(int);
  54.    local void handler(int);
  55.    local void license(void);
  56.    local void help(void);
  57.    local void zipstdout(void);
  58.    void main(int, char **);
  59.    local int count_args(char *s);
  60.    local void envargs(int *Pargc, char ***Pargv, char *envstr);
  61. #endif /* PROTO */
  62.  
  63.  
  64.  
  65. local void freeup()
  66. /* Free all allocations in the found list and the zfiles list */
  67. {
  68.   struct flist far *f;  /* steps through found list */
  69.   struct zlist far *z;  /* pointer to next entry in zfiles list */
  70.  
  71.   for (f = found; f != NULL; f = fexpel(f))
  72.     ;
  73.   while (zfiles != NULL)
  74.   {
  75.     z = zfiles->nxt;
  76.     free((voidp *)(zfiles->name));
  77.     free((voidp *)(zfiles->zname));
  78.     if (zfiles->ext)
  79.       free((voidp *)(zfiles->extra));
  80.     if (zfiles->cext && zfiles->cextra != zfiles->extra)
  81.       free((voidp *)(zfiles->cextra));
  82.     if (zfiles->com)
  83.       free((voidp *)(zfiles->comment));
  84.     farfree((voidp far *)zfiles);
  85.     zfiles = z;
  86.     zcount--;
  87.   }
  88. }
  89.  
  90.  
  91. local void leave(e)
  92. int e;                  /* exit code */
  93. /* Process -o and -m options (if specified), free up malloc'ed stuff, and
  94.    exit with the code e. */
  95. {
  96.   int r;                /* return value from trash() */
  97.   ulg t;                /* latest time in zip file */
  98.   struct zlist far *z;  /* pointer into zfile list */
  99.  
  100.   /* If latest, set time to zip file to latest file in zip file */
  101.   if (latest && strcmp(zipfile, "-"))
  102.   {
  103.     diag("changing time of zip file to time of latest file in it");
  104.     /* find latest time in zip file */
  105.     if (zfiles == NULL)
  106.        warn("zip file is empty, can't make it as old as latest entry", "");
  107.     else {
  108.       t = zfiles->tim;
  109.       for (z = zfiles->nxt; z != NULL; z = z->nxt)
  110.         if (t < z->tim)
  111.           t = z->tim;
  112.       /* set modified time of zip file to that time */
  113.       stamp(zipfile, t);
  114.     }
  115.   }
  116.   if (tempath != NULL)
  117.   {
  118.     free((voidp *)tempath);
  119.     tempath = NULL;
  120.   }
  121.   if (zipfile != NULL)
  122.   {
  123.     free((voidp *)zipfile);
  124.     zipfile = NULL;
  125.   }
  126.  
  127.  
  128.   /* If dispose, delete all files in the zfiles list that are marked */
  129.   if (dispose)
  130.   {
  131.     diag("deleting files that were added to zip file");
  132.     if ((r = trash()) != ZE_OK)
  133.       err(r, "was deleting moved files and directories");
  134.   }
  135.  
  136.  
  137.   /* Done! */
  138.   freeup();
  139. #ifdef VMS
  140.   exit(0);
  141. #else /* !VMS */
  142.   exit(e);
  143. #endif /* ?VMS */
  144. }
  145.  
  146.  
  147. void err(c, h)
  148. int c;                  /* error code from the ZE_ class */
  149. char *h;                /* message about how it happened */
  150. /* Issue a message for the error, clean up files and memory, and exit. */
  151. {
  152.   static int error_level;
  153.   if (error_level++ > 0) exit(0);  /* avoid recursive err() */
  154.  
  155.   if (PERR(c))
  156.     perror("zip error");
  157.   fprintf(stderr, "zip error: %s (%s)\n", errors[c-1], h);
  158.   if (tempzip != NULL)
  159.   {
  160.     if (tempzip != zipfile) {
  161.       if (tempzf != NULL)
  162.         fclose(tempzf);
  163. #ifndef DEBUG
  164.       destroy(tempzip);
  165. #endif
  166.       free((voidp *)tempzip);
  167.     } else {
  168.       /* -g option, attempt to restore the old file */
  169.       int k = 0;                        /* keep count for end header */
  170.       ulg cb = cenbeg;                  /* get start of central */
  171.       struct zlist far *z;  /* steps through zfiles linked list */
  172.  
  173.       fprintf(stderr, "attempting to restore %s to its previous state\n",
  174.          zipfile);
  175.       fseek(tempzf, cenbeg, SEEK_SET);
  176.       tempzn = cenbeg;
  177.       for (z = zfiles; z != NULL; z = z->nxt)
  178.       {
  179.         putcentral(z, tempzf);
  180.         tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
  181.         k++;
  182.       }
  183.       putend(k, tempzn - cb, cb, zcomlen, zcomment, tempzf);
  184.       tempzf = NULL;
  185.       fclose(tempzf);
  186.     }
  187.   }
  188.   if (key != NULL)
  189.     free((voidp *)key);
  190.   if (tempath != NULL)
  191.     free((voidp *)tempath);
  192.   if (zipfile != NULL)
  193.     free((voidp *)zipfile);
  194.   freeup();
  195. #ifdef VMS
  196.   c = 0;
  197. #endif
  198.   exit(c);
  199. }
  200.  
  201.  
  202. void error(h)
  203.   char *h;
  204. /* Internal error, should never happen */
  205. {
  206.   err(ZE_LOGIC, h);
  207. }
  208.  
  209. local void handler(s)
  210. int s;                  /* signal number (ignored) */
  211. /* Upon getting a user interrupt, turn echo back on for tty and abort
  212.    cleanly using err(). */
  213. {
  214. #ifndef MSDOS
  215. # ifdef CRYPT
  216.    echon();
  217. # endif
  218.   putc('\n', stderr);
  219. #endif /* !MSDOS */
  220.   err(ZE_ABORT, "aborting");
  221.   s++;                                  /* keep some compilers happy */
  222. }
  223.  
  224.  
  225. void warn(a, b)
  226. char *a, *b;            /* message strings juxtaposed in output */
  227. /* Print a warning message to stderr and return. */
  228. {
  229.   fprintf(stderr, "zip warning: %s%s\n", a, b);
  230. }
  231.  
  232.  
  233. local void license()
  234. /* Print license information to stdout. */
  235. {
  236.   extent i;             /* counter for copyright array */
  237.  
  238.   for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
  239.     printf(copyright[i], "zip");
  240.     putchar('\n');
  241.   }
  242.   for (i = 0; i < sizeof(disclaimer)/sizeof(char *); i++)
  243.     puts(disclaimer[i]);
  244. }
  245.  
  246.  
  247. local void help()
  248. /* Print help (along with license info) to stdout. */
  249. {
  250.   extent i;             /* counter for help array */
  251.  
  252.   /* help array */
  253.   static char *text[] = {
  254. "",
  255. "Zip %d.%d (%s). Usage:",
  256. "zip [-options] [-b path] [-t mmddyy] [-n suffixes] [zipfile list] [-x list]",
  257. "  The default action is to add or replace zipfile entries from list, which",
  258. "  can include the special name - to compress standard input.",
  259. "  If zipfile and list are ommitted, zip compresses stdin to stdout.",
  260. "  -f   freshen: only changed files  -u   update: only changed or new files",
  261. "  -d   delete entries in zipfile    -m   move into zipfile (delete files)",
  262. "  -k   simulate PKZIP made zipfile  -g   allow growing existing zipfile",
  263. "  -h   show this help               -L   show software license",
  264. "  -r   recurse into directories     -j   junk (don't record) directory names",
  265. "  -0   store only                   -l   translate end-of-line",
  266. "  -1   compress faster              -9   compress better",
  267. "  -q   quiet operation              -n   don't compress these suffixes",
  268. "  -c   add one-line comments        -z   add zipfile comment",
  269. "  -b   use \"path\" for temp files    -t   only do files after \"mmddyy\"",
  270. "  -@   read names from stdin        -o   make zipfile as old as latest entry",
  271. #ifdef CRYPT
  272. "  -e   encrypt  (-ee verify key)",
  273. #endif
  274. #ifdef VMS
  275. "  -w   append the VMS version number to the name stored in the zip file",
  276. "  -V   save VMS file attributes",
  277. #endif /* VMS */
  278. #ifdef OS2
  279. "  -E   use the .LONGNAME Extended attribute (if found) as filename",
  280. #endif /* OS2 */
  281. #ifdef S_IFLNK
  282. "  -y   store symbolic links as the link instead of the referenced file",
  283. #endif /* !S_IFLNK */
  284. "  -x   exclude the names that follow from those operated on"
  285.   };
  286.  
  287.   for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
  288.   {
  289.     printf(copyright[i], "zip");
  290.     putchar('\n');
  291.   }
  292.   for (i = 0; i < sizeof(text)/sizeof(char *); i++)
  293.   {
  294.     printf(text[i], REVISION / 10, REVISION % 10, REVDATE);
  295.     putchar('\n');
  296.   }
  297. }
  298.  
  299.  
  300. /* Do